package net.qiqbframework.modelling.command.handling;

import net.qiqbframework.messaging.GenericMessage;
import net.qiqbframework.messaging.Message;
import net.qiqbframework.messaging.MessageDecorator;
import net.qiqbframework.messaging.MetaData;

import javax.annotation.Nonnull;
import java.util.Map;


public class GenericBusinessMessage<T> extends MessageDecorator<T> implements BusinessMessage<T> {

    private final String commandName;

    /**
     * 将一个对象组装一个命令消息
     *
     * @param command
     * @param <C>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <C> BusinessMessage<C> of(@Nonnull Object command) {
        if (command instanceof BusinessMessage) {
            return (BusinessMessage<C>) command;
        } else if (command instanceof Message) {
            return new GenericBusinessMessage<>(
                    (C) ((Message<?>) command).getPayload(), ((Message<?>) command).getMetaData()
            );
        }
        return new GenericBusinessMessage<>((C) command, MetaData.emptyInstance());
    }


    public GenericBusinessMessage(@Nonnull T payload) {
        this(payload, MetaData.emptyInstance());
    }

    public GenericBusinessMessage(@Nonnull T payload, @Nonnull Map<String, ?> metaData) {
        this(new GenericMessage<>(payload, metaData), payload.getClass().getName());
    }

    public GenericBusinessMessage(@Nonnull Message<T> delegate, @Nonnull String commandName) {
        super(delegate);
        this.commandName = commandName;
    }

    @Override
    public String getAggregateName() {
        return commandName;
    }


    @Override
    protected void describeTo(StringBuilder stringBuilder) {
        super.describeTo(stringBuilder);
        stringBuilder.append(", commandName='")
                .append(getAggregateName())
                .append('\'');
    }

    @Override
    protected String describeType() {
        return "GenericBusinessMessage";
    }


}
